package com.chunk.servlet;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.chunk.util.Cons;
import com.sun.javafx.iio.ios.IosDescriptor;

/**
 * 合并分片文件+验证分片正确性
 * @author 王远航
 *
 */
@WebServlet(name = "FileChunkCheckAndMergeServlet", urlPatterns = "/chunkCheckAndMerge")
public class FileChunkCheckAndMergeServlet extends HttpServlet {

    private static final Logger commonLogger = LoggerFactory.getLogger(FileChunkCheckAndMergeServlet.class);

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		super.doGet(request, response);
		doPost(request, response);

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) {
		String action = request.getParameter("action");
		
		try {
			if (action.equals("mergeChunks")) { // 文件传输完成标记处理合并逻辑
				String fileMd5 = request.getParameter("fileMd5"); // 合并文件，需要合并的文件的目录标记
				File f = new File(Cons.FILE_PATH_UPLOAD_CHUNKS + "/" + fileMd5); // 读取目录里的所有文件
				File[] fileArray = f.listFiles(new FileFilter() { // 取出文件夹内所有的文件
					@Override
					public boolean accept(File pathname) {
						if (pathname.isDirectory()) { // 排除目录只要文件
							return false;
						}
						return true;
					}
				});
	
				List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));// 转成集合，便于排序
				Collections.sort(fileList, new Comparator<File>() {
					@Override
					public int compare(File o1, File o2) { // 集合排序
						if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {
							return -1;
						}
						return 1;
					}
				});
				
				File intsFile = new File(Cons.FILE_PATH_UPLOAD_INTS); //创建完整文件目录
				if (!intsFile.exists()) {
					intsFile.mkdir();
				}
				
				String fileName = request.getParameter("fileName"); // 获取文件名称
				String suffix = fileName.substring(fileName.lastIndexOf(".")); // 拿到文件格式
				
				File outputFile = new File(Cons.FILE_PATH_UPLOAD_INTS + "/" + fileMd5 + suffix);
				outputFile.createNewFile(); // 创建文件
				FileChannel outChnnel = new FileOutputStream(outputFile).getChannel(); // 输出流
	
				FileChannel inChannel; // 开始合并
				for (File file : fileList) {
					inChannel = new FileInputStream(file).getChannel();
					inChannel.transferTo(0, inChannel.size(), outChnnel);
					inChannel.close();
					file.delete(); // 删除分片
				}
				outChnnel.close();
	
				File tempFile = new File(Cons.FILE_PATH_UPLOAD_CHUNKS + "/" + fileMd5); // 清除文件夹
				if (tempFile.isDirectory() && tempFile.exists()) {
					tempFile.delete();
				}
				commonLogger.debug("合并成功！,Info: {}" ,fileMd5);
			} else if (action.equals("checkChunk")) { // 分片验证
				String fileMd5 = request.getParameter("fileMd5"); // 检查当前分块是否上传成功
				String chunk = request.getParameter("chunk");
				String chunkSize = request.getParameter("chunkSize");
	
				File checkFile = new File(Cons.FILE_PATH_UPLOAD_CHUNKS + "/" + fileMd5 + "/" + chunk);
				response.setContentType("text/html;charset=utf-8");
	
				if (checkFile.exists() && checkFile.length() == Integer.parseInt(chunkSize)) { // 检查文件是否存在，且大小是否一致
					response.getWriter().write("{\"ifExist\":1}"); // 上传过
				} else { // 没有上传过
					response.getWriter().write("{\"ifExist\":0}");
				}
			}
		} catch (IOException e) {
			commonLogger.debug("验证或合并文件失败,Info: {}" ,e.getMessage());
			
		}
	}
}
